# services/keyword.py
"""
Author: didiplus
Description: 关键词服务类
Date: 2025-08-20 20:54:00
LastEditors: didiplus
LastEditTime: 2025-08-20 20:54:00
FilePath: /WeChatBot/app/services/keyword.py
Version: 1.0
"""
from sqlalchemy.orm import Session
from typing import Optional, List
from datetime import datetime

from models.keywords import KeywordRuleModel
from schemas.keyword import KeywordRuleCreate, KeywordRuleUpdate, TextInput, MatchResult, KeywordResponse

class KeywordRuleService:
    """
    关键词规则服务类
    提供关键词规则相关的业务逻辑处理
    """
    
    def __init__(self, db: Session):
        """
        初始化关键词规则服务
        
        Args:
            db (Session): 数据库会话对象
        """
        self.db = db
    
    def create_keyword_rule(self, user_id: int, rule_create: KeywordRuleCreate) -> KeywordRuleModel:
        """
        创建关键词规则
        
        Args:
            user_id (int): 用户ID
            rule_create (KeywordRuleCreate): 关键词规则创建数据
            
        Returns:
            KeywordRuleModel: 创建的关键词规则对象
        """
        db_rule = KeywordRuleModel(
            keyword=rule_create.keyword,
            response=rule_create.response,
            priority=rule_create.priority,
            case_sensitive=rule_create.case_sensitive,
            exact_match=rule_create.exact_match,
            description=rule_create.description,
            user_id=user_id
        )
        
        self.db.add(db_rule)
        self.db.commit()
        self.db.refresh(db_rule)
        return db_rule
    
    def get_keyword_rule_by_id(self, rule_id: int) -> Optional[KeywordRuleModel]:
        """
        根据ID获取关键词规则
        
        Args:
            rule_id (int): 规则ID
            
        Returns:
            Optional[KeywordRuleModel]: 关键词规则对象，如果不存在返回None
        """
        return self.db.query(KeywordRuleModel).filter(
            KeywordRuleModel.id == rule_id,
            KeywordRuleModel.is_active == True
        ).first()
    
    def get_keyword_rules_by_user(self, user_id: int, skip: int = 0, limit: int = 100) -> List[KeywordRuleModel]:
        """
        获取用户的所有关键词规则
        
        Args:
            user_id (int): 用户ID
            skip (int): 跳过的记录数
            limit (int): 返回的记录数
            
        Returns:
            List[KeywordRuleModel]: 关键词规则列表
        """
        return self.db.query(KeywordRuleModel).filter(
            KeywordRuleModel.user_id == user_id,
            KeywordRuleModel.is_active == True
        ).offset(skip).limit(limit).all()
    
    def get_active_keyword_rules_by_user(self, user_id: int) -> List[KeywordRuleModel]:
        """
        获取用户的所有激活状态的关键词规则
        
        Args:
            user_id (int): 用户ID
            
        Returns:
            List[KeywordRuleModel]: 激活状态的关键词规则列表
        """
        return self.db.query(KeywordRuleModel).filter(
            KeywordRuleModel.user_id == user_id,
            KeywordRuleModel.is_active == True
        ).all()
    
    def update_keyword_rule(self, rule_id: int, user_id: int, rule_update: KeywordRuleUpdate) -> Optional[KeywordRuleModel]:
        """
        更新关键词规则
        
        Args:
            rule_id (int): 规则ID
            user_id (int): 用户ID（用于权限验证）
            rule_update (KeywordRuleUpdate): 关键词规则更新数据
            
        Returns:
            Optional[KeywordRuleModel]: 更新后的关键词规则对象，如果规则不存在或无权限返回None
        """
        db_rule = self.get_keyword_rule_by_id(rule_id)
        if not db_rule:
            return None
        
        # 验证用户权限
        if db_rule.user_id != user_id:
            return None
        
        # 更新规则信息
        update_data = rule_update.dict(exclude_unset=True)
        for field, value in update_data.items():
            if value is not None:
                setattr(db_rule, field, value)
        
        db_rule.updated_at = datetime.now()
        self.db.commit()
        self.db.refresh(db_rule)
        return db_rule
    
    def delete_keyword_rule(self, rule_id: int, user_id: int) -> bool:
        """
        删除关键词规则（软删除）
        
        Args:
            rule_id (int): 规则ID
            user_id (int): 用户ID（用于权限验证）
            
        Returns:
            bool: 删除成功返回True，规则不存在或无权限返回False
        """
        db_rule = self.get_keyword_rule_by_id(rule_id)
        if not db_rule:
            return False
        
        # 验证用户权限
        if db_rule.user_id != user_id:
            return False
        
        db_rule.is_active = False
        db_rule.updated_at = datetime.now()
        self.db.commit()
        return True
    
    def match_text_with_rules(self, text: str, user_id: int) -> MatchResult:
        """
        根据用户定义的关键词规则匹配文本
        
        Args:
            text (str): 待匹配的文本
            user_id (int): 用户ID
            
        Returns:
            MatchResult: 匹配结果
        """
        # 获取用户的所有激活规则
        active_rules = self.get_active_keyword_rules_by_user(user_id)
        
        matched_results: List[KeywordResponse] = []
        
        for rule in active_rules:
            # 根据规则进行匹配
            if rule.exact_match:
                if rule.case_sensitive:
                    is_match = text == rule.keyword
                else:
                    is_match = text.lower() == rule.keyword.lower()
            else:
                if rule.case_sensitive:
                    is_match = rule.keyword in text
                else:
                    is_match = rule.keyword.lower() in text.lower()
            
            if is_match:
                matched_results.append(KeywordResponse(
                    keyword=rule.keyword,
                    response=rule.response,
                    matched=True,
                    priority=rule.priority
                ))
        
        # 按优先级排序，返回最佳匹配
        if matched_results:
            best_match = sorted(matched_results, key=lambda x: x.priority or 0)[0]
            return MatchResult(
                matched_keywords=matched_results,
                best_match=best_match
            )
        else:
            return MatchResult(
                matched_keywords=[],
                best_match=KeywordResponse(
                    keyword="",
                    response="未识别到有效关键词，请尝试其他输入。",
                    matched=False
                )
            )